<template>
  <div id="cesiumContainer"></div>
</template>
<script setup>
import * as Cesium from "cesium";
import TOKEN from "@/utils/cesium/token.js";
import { showInfoBox } from "./compoments/ShowInfo/index";
import Slot from "./compoments/ShowInfo/slot.vue";

let cesiumViewer = ref(null);

onMounted(() => {
  initPage();
  const billBoardList = [
    {
      position: [114.30527350657182, 30.59595484998685],
      name: "肖总",
    },
    {
      position: [114.36687292429713, 30.573724426095062],
      name: "花总",
    },
    {
      position: [114.26522916206015, 30.59026470545458],
      name: "小沈",
    },
  ];
  addBillBoard(billBoardList);
  addEvent();
  // 函数式组件
  // showInfoBox({ positionLeft: "200px", positionTop: "300px", slot: Slot });
});

function addEvent() {
  const viewer = cesiumViewer.value;
  const scene = viewer.scene;
  const camera = viewer.camera;
  const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.setInputAction((event) => {
    // 屏幕坐标
    const cartesian2 = event.position;
    console.log("左键点击", cartesian2);
    // // 判断是有有物体被点击
    const pick = viewer.scene.pick(cartesian2);
    if (pick) {
      // 显示弹出层
      console.log("pick", pick);
      // 1 点击坐标转 世界坐标
      const cartesian3 = viewer.scene.globe.pick(
        viewer.camera.getPickRay(cartesian2),
        viewer.scene
      );
      const cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
      console.log("弧度坐标 cartographic", cartographic);
      // 2. 弧度坐标转（角坐标）经纬度、高度
      const lon = Cesium.Math.toDegrees(cartographic.longitude);
      const lat = Cesium.Math.toDegrees(cartographic.latitude);
      // 3. 得到 经度、纬度、高度
      console.log(lon, lat, cartographic.height);
      console.log("e", event);
      const data = {
        layerId: "layer1", // 英文，且唯一,内部entity会用得到
        lon: lon,
        lat: lat,
        element: "#one", // 弹框的唯一id
        boxHeightMax: 0, // 中间立方体的最大高度
      };

      showDynamicLayer(viewer, data, () => {
        // 回调函数 改变弹窗的内容;
        // this.popData.title = pick.id.name;
        // this.popData.pointId = pick.id.id;
      });
    } else {
      // 关闭弹出层
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}

// 创建一个动态实体弹窗
function showDynamicLayer(viewer, data, callback) {
  callback();
  // 添加div弹窗
  const lon = data.lon * 1,
    lat = data.lat * 1;
  // data.boxHeightMax为undef也没事
  var divPosition = Cesium.Cartesian3.fromDegrees(lon, lat, data.boxHeightMax);
  // 当为true的时候，表示当element在地球背面会自动隐藏。默认为false，置为false，不会这样。但至少减轻判断计算压力
  creatHtmlElement(viewer, data.element, divPosition, [10, 0], true);
}

// 创建一个 htmlElement元素 并且，其在earth背后会自动隐藏
function creatHtmlElement(viewer, element, position, arr, flog) {
  var ele = document.querySelector(element);
  var scratch = new Cesium.Cartesian2(); // cesium二维笛卡尔 笛卡尔二维坐标系就是我们熟知的而二维坐标系；三维也如此
  var scene = viewer.scene,
    camera = viewer.camera;
  // 更新之前执行的函数
  scene.preRender.addEventListener(() => {
    // 对应的canvas 坐标
    var canvasPosition = scene.cartesianToCanvasCoordinates(position, scratch); // cartesianToCanvasCoordinates 笛卡尔坐标（3维度）到画布坐标
    if (Cesium.defined(canvasPosition)) {
      const left = canvasPosition.x + arr[0] + "px";
      const top = canvasPosition.y + arr[1] + "px";
      /* 此处进行判断**/ // var px_position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, cartesian)
      if (flog && flog == true) {
        var e = position,
          i = camera.position,
          n = scene.globe.ellipsoid.cartesianToCartographic(i).height;
        if (
          !((n += 1 * scene.globe.ellipsoid.maximumRadius),
          Cesium.Cartesian3.distance(i, e) > n)
        ) {

          showInfoBox({el:'cesiumContainer', positionLeft:left, positionTop: top, slot: Slot });
          console.log("show", left, top);
        } else {
          console.log("hide", left, top);
        }
      }
    }
  });
}

function addBillBoard(list) {
  cesiumViewer.value.entities.removeAll();
  const imageUrl = "/src/assets/image/position.png";
  list.forEach((item) => {
    cesiumViewer.value.entities.add({
      position: Cesium.Cartesian3.fromDegrees(
        item.position[0],
        item.position[1],
        0
      ),
      billboard: {
        image: imageUrl,
        color: Cesium.Color.RED,
        scale: 0.2,
      },
      label: {
        text: item.name,
        font: "20px",
        color: Cesium.Color.RED,
        pixelOffset: new Cesium.Cartesian2(0, -40),
        fillColor: Cesium.Color.BLUE,
        showBackground: false,
        backgroundColor: Cesium.Color.RED,
      },
    });
  });
}

function initPage() {
  Cesium.Ion.defaultAccessToken = TOKEN;

  // 实例化
  const viewer = new Cesium.Viewer("cesiumContainer", {
    // 界面控件 全部关闭
    timeline: false, // 时间轴控件
    animation: false, // 动画控件
    geocoder: false, // 搜索按钮
    homeButton: false, // 主页按钮
    sceneModePicker: false, // 投影方式按钮
    baseLayerPicker: false, // 图层选择按钮
    navigationHelpButton: false, // 帮助手势按钮
    fullscreenButton: false, // 全屏按钮
  });
  // 隐藏版权信息
  viewer.cesiumWidget.creditContainer.style.display = "none";
  // style 6-影像 7-矢量 8-标注
  var aMapProvider = new Cesium.UrlTemplateImageryProvider({
    url: "https://webst0{s}.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}&lang=zh_cn&size=1",
    subdomains: ["1", "2", "3", "4"], // 如果有多个子域名用于负载均衡，可以在这里指定
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    minimumLevel: 3,
    maximumLevel: 18, // 根据高德地图的实际最大层级设置
  });
  // 将高德地图添加到Cesium Viewer中
  viewer.imageryLayers.addImageryProvider(aMapProvider);

  // 设置初始位置  Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result)
  const boundingSphere = new Cesium.BoundingSphere(
    Cesium.Cartesian3.fromDegrees(114.30527350657182, 30.59595484998685, 0),
    100
  );
  cesiumViewer.value = viewer;
}
</script>

<style scoped>
#cesiumContainer {
  width: 100%;
  height: 100%;
}
</style>
